package org.aurora.framework.boot.mybatis.flex.processor.utils;

import javax.annotation.processing.Filer;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.*;
import java.util.*;

/**
 * name: FileUtil
 * <p>
 * desc:
 * </p>
 * create date: 2024-10-31 18:46:17
 *
 * @author cao.yong
 */
public class FileUtil {

    private static final Set<String> FLAG_FILE_NAMES = new HashSet<>(List.of("pom.xml", "build.gradle", "build.gradle.kts"));
    private static final String RESOURCE_PATH = "src" + File.separator + "main" + File.separator + "resources";
    private static final String JAVA_PATH = "src" + File.separator + "main" + File.separator + "java";

    private static boolean existFlagFile(String dir) {
        for (String flagName : FLAG_FILE_NAMES) {
            Path path = Paths.get(dir, flagName);
            return Files.exists(path, LinkOption.NOFOLLOW_LINKS);
        }
        return false;
    }

    public static InputStream getInputStream(Filer filer, String fileName) {
        try {
            String root = getRootPath(filer);
            if (root != null) {
                Path path = Paths.get(root, RESOURCE_PATH, fileName);
                System.out.println("config file: " + path.toAbsolutePath());
                return Files.newInputStream(path, StandardOpenOption.READ);
            }
            return null;
        } catch (IOException e) {
            System.out.println("Load processor config file failed: " + e.getMessage());
            return null;
        }
    }

    public static FileWriter createFileWriter(Filer filer, String packageName, String fileName) {
        try {
            String root = getRootPath(filer);
            if (root != null) {
                Path dirPath = Paths.get(root, JAVA_PATH, packageName);
                if (!dirPath.toFile().exists()) {
                    Files.createDirectories(dirPath);
                }
                Path filePath = Paths.get(root, JAVA_PATH, packageName, fileName);
                System.out.println("java file path: " + filePath.toAbsolutePath());
                if (Files.exists(filePath, LinkOption.NOFOLLOW_LINKS)) {
                    return null;
                }
                boolean isCreated = filePath.toFile().createNewFile();
                if (isCreated) {
                    return new FileWriter(filePath.toFile());
                }
            }
            return null;
        } catch (IOException e) {
            System.out.println("Create File writer failed: " + e.getMessage());
            return null;
        }
    }

    public static String getRootPath(Filer filer) throws IOException {
        FileObject resource = filer.getResource(StandardLocation.CLASS_OUTPUT, "", "aurora");
        if (Objects.isNull(resource)) {
            resource = filer.createResource(StandardLocation.CLASS_OUTPUT, "", "aurora");
        }
        Path classPath = Paths.get(resource.toUri()).getParent();
        // 临时资源创建完成获取路径后，删除
        resource.delete();
        return getModuleRootPath(classPath, 10);
    }

    public static String getModuleRootPath(Path path, int depth) {
        if (depth <= 0 || path == null) {
            return null;
        }
        if (Files.isRegularFile(path)) {
            return getModuleRootPath(path.getParent(), depth - 1);
        } else {
            if (existFlagFile(path.toAbsolutePath().toString())) {
                return path.toAbsolutePath().toString();
            } else {
                return getModuleRootPath(path.getParent(), depth - 1);
            }
        }
    }
}
